//
//  AccidentsDetection.m
//  BCN Emergencies
//
//  Created by Luis Enrique López Martínez on 15/12/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "AccidentsDetection.h"

@implementation AccidentsDetection

@synthesize locationManager, delegate;

#pragma mark - private methods
-(double)biggerAccelerationWithAcceleration:(UIAcceleration *)acceleration {
    
    double maxAccelerationValue;
    
    if (acceleration.x > acceleration.y && acceleration.x >acceleration.z) {
        maxAccelerationValue = acceleration.x;
    } else if (acceleration.y > acceleration.x && acceleration.y >acceleration.z) {
        maxAccelerationValue = acceleration.y;
    } else {
        maxAccelerationValue = acceleration.z;
    }    
    return maxAccelerationValue;
}

-(void)checkAccident {
    
    if ([self isAccidentDetected]) {
        [delegate accidentDetected];
    }
}

#pragma mark - class methods

-(void)startTrackingAccidentDetection {
    
    NSLog(@"startTracking possible accident");
    
    // init values
    maxAcceleration = 0.0;
    isSoundBiggerThanThershold = 1;
    isTravelingSlowerThanMST = 0;
    distanceTraveledSlowerThanMST = 0.0;
    
    // Init accelerometer
	accelerometer = [UIAccelerometer sharedAccelerometer];
	[accelerometer setUpdateInterval:0.25f];
	[accelerometer setDelegate:self];
    
    // Check if user has location enabled and init GPS
    if([CLLocationManager locationServicesEnabled])
    {
    // Standard change coordinates
        NSLog(@"START UPDATING LOCATION");
        [self.locationManager startUpdatingLocation];
    }

    
    //start checking accident
    NSTimer *checkAccidentTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                                                   target:self selector:@selector(checkAccident)
                                                                 userInfo:nil
      
                                                                  repeats:YES];
}

-(BOOL)isAccidentDetected {
    
    BOOL isAccident = NO;
    //An accident detection can be triggered by one of two situations: 
    NSLog(@"%f",((maxAcceleration / minimunAccelerationThershold) + (soundFactor * isSoundBiggerThanThershold)));
    //(1) a high acceleration event and a high decibel sound event are recorded while the vehicle is moving above the threshold speed, minimumSpeedThershold 
    BOOL isHighAccelerationAndHighSound = (((maxAcceleration / minimunAccelerationThershold) + (soundFactor * isSoundBiggerThanThershold)) >= accidentDetectionThershold) && (isTravelingSlowerThanMST == 1);
    
    //(2) the distance moved since the last time the speed threshold MinimumSpeedThershold was exceeded is less than minimumDistanceTraveledSlowerThanMSTAfterAnAccidentDetectionIsDeactivated feet and an acceleration and sound event occur
//    BOOL isDistanceExceededSinceLastEvent = (distanceTraveledSlowerThanMST < minimumDistanceTraveledBeforeAccidentDetectionIsDeactivated) &&
    ((maxAcceleration / minimunAccelerationThershold) + (soundFactor * isSoundBiggerThanThershold) >= accidentDetectionThershold);
    
    BOOL isDistanceExceededSinceLastEvent = NO;
    
    if (isHighAccelerationAndHighSound || isDistanceExceededSinceLastEvent) {
        isAccident = YES;
        NSLog(@"yes");
    }
    
    NSLog(@"Accident detected %i", isAccident);
    return isAccident;
}

#pragma mark - UIAccelerometer Delegate Methods

- (void)accelerometer:(UIAccelerometer *)meter didAccelerate:(UIAcceleration *)acceleration {
	
    if ([self biggerAccelerationWithAcceleration:acceleration] > maxAcceleration) {
        maxAcceleration = acceleration.x;
    }
    NSLog(@"Max accel = %f", maxAcceleration);
}

#pragma mark -
#pragma mark Location manager

/**
 Return a location manager -- create one if necessary.
 */
- (CLLocationManager *)locationManager {
	if (locationManager != nil)
		return locationManager;
	
	locationManager = [[CLLocationManager alloc] init];
	[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    [locationManager setDistanceFilter:1];
	[locationManager setDelegate:self];
	
	return locationManager;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{
    NSLog(@"position updated");
    int isCurrentlyTravelingSlower = isTravelingSlowerThanMST;
    isTravelingSlowerThanMST = ([newLocation speed] * metersSecondToMilesPerHour) < minimumSpeedThershold;
    if (isTravelingSlowerThanMST == 0) {
        distanceTraveledSlowerThanMST = 0;
    } else if (isCurrentlyTravelingSlower) {
       distanceTraveledSlowerThanMST = distanceTraveledSlowerThanMST + [newLocation distanceFromLocation:oldLocation];
    } else {
        distanceTraveledSlowerThanMST = [newLocation distanceFromLocation:oldLocation];
    }
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
	[self.locationManager stopUpdatingLocation];
}

@end
